package com.cl.bootws.listener;

import com.cl.bootws.config.MessageConfigurator;
import com.cl.bootws.message.*;
import jakarta.websocket.*;
import jakarta.websocket.server.PathParam;
import jakarta.websocket.server.ServerEndpoint;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.nio.ByteBuffer;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

@ServerEndpoint(value = "/message/{username}",
        encoders = {WsMessageEncoder.class},
        decoders = {WsMessageDecoder.class},
        subprotocols = {"gmsg"},
        configurator = MessageConfigurator.class)
@Component
@Slf4j
public class WSMessageListener {

    public static ConcurrentMap<String, UserSession> sessions = new ConcurrentHashMap<>();

    private UserSession userSession;

    @OnOpen
    public void onOpen(Session session, EndpointConfig config, @PathParam("username") String username) {
        userSession = new UserSession(session.getId(), username, session);
        sessions.put(username, userSession);
        log.info("【{}】用户进入, 当前连接数：{}", username, sessions.size());
    }

    @OnClose
    public void onClose(Session session, CloseReason reason) {
        UserSession userSession = sessions.remove(session.getId());
        if (userSession != null) {
            log.info("用户【{}】, 断开连接, 当前连接数：{}", userSession.getUsername(), sessions.size());
        }
    }

    @OnMessage
    public void pongMessage(Session session, PongMessage message) {
        ByteBuffer buffer = message.getApplicationData();
        log.debug("接受到Pong帧【这是由浏览器发送】：" + buffer.toString());
    }

    @OnMessage
    public void onMessage(Session session, AbstractMessage message) {
        if (message instanceof PingMessage) {
            log.debug("这里是ping消息");
            return;
        }
        if (message instanceof PersonMessage personMessage) {
            if (userSession.getUsername().equals(personMessage.getToName())) {
                log.info("【{}】收到消息：{}", userSession.getUsername(), personMessage.getContent());
            } else {
                UserSession userSession = sessions.get(personMessage.getToName());
                if (userSession != null) {
                    userSession.getSession().getAsyncRemote().sendObject(message);
                }
            }
            return;
        }
        if (message instanceof SystemMessage) {
            log.info("接受到消息类型为【系统消息】");
        }
    }

    @OnError
    public void onError(Session session, Throwable error) {
        log.error(error.getMessage());
    }
}
